#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2024/7/8 13:44
# @File    : canvas_app.py
# @Description : -i http://pypi.tuna.tsinghua.edu.cn/simple/ --trusted-host pypi.tuna.tsinghua.edu.cn


"""
本代码由[Tkinter布局助手]生成
官网:https://www.pytk.net
QQ交流群:905019785
在线反馈:https://support.qq.com/product/618914
"""
import time

import cv2
import tkinter
import random
from tkinter import ttk, Tk, Canvas, Label, BOTH, YES
from tkinter.ttk import *
from threading import Thread
from tkinter import messagebox
from PIL import Image, ImageTk



class WinGUI(Tk):
    def __init__(self):
        super().__init__()
        self.__win()
        self.tk_button_open = self.__tk_button_lyck9g7u(self)
        self.tk_button_close = self.__tk_button_lyck9i7l(self)
        self.tk_canvas_canvas = self.__tk_canvas_lyck9nuu(self)
        #self.video = cv2.VideoCapture(0, cv2.CAP_DSHOW)
        self.video = None
        self.video_open = False
        # 关闭程序时 先关闭掉opencv相关信息
        self.protocol("WM_DELETE_WINDOW", self._close_cv2)

    def _close_cv2(self):
        print("close...")
        if self.video_open:
            #self.close_video()
            self.video.release()
        cv2.destroyAllWindows()
        self.quit()
        self.destroy()

    def __win(self):
        self.title("Tkinter布局助手")
        # 设置窗口大小、居中
        width = 389
        height = 312
        screenwidth = self.winfo_screenwidth()
        screenheight = self.winfo_screenheight()
        geometry = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)
        self.geometry(geometry)

        self.resizable(width=False, height=False)

    def scrollbar_autohide(self, vbar, hbar, widget):
        """自动隐藏滚动条"""

        def show():
            if vbar: vbar.lift(widget)
            if hbar: hbar.lift(widget)

        def hide():
            if vbar: vbar.lower(widget)
            if hbar: hbar.lower(widget)

        hide()
        widget.bind("<Enter>", lambda e: show())
        if vbar: vbar.bind("<Enter>", lambda e: show())
        if vbar: vbar.bind("<Leave>", lambda e: hide())
        if hbar: hbar.bind("<Enter>", lambda e: show())
        if hbar: hbar.bind("<Leave>", lambda e: hide())
        widget.bind("<Leave>", lambda e: hide())

    def v_scrollbar(self, vbar, widget, x, y, w, h, pw, ph):
        widget.configure(yscrollcommand=vbar.set)
        vbar.config(command=widget.yview)
        vbar.place(relx=(w + x) / pw, rely=y / ph, relheight=h / ph, anchor='ne')

    def h_scrollbar(self, hbar, widget, x, y, w, h, pw, ph):
        widget.configure(xscrollcommand=hbar.set)
        hbar.config(command=widget.xview)
        hbar.place(relx=x / pw, rely=(y + h) / ph, relwidth=w / pw, anchor='sw')

    def create_bar(self, master, widget, is_vbar, is_hbar, x, y, w, h, pw, ph):
        vbar, hbar = None, None
        if is_vbar:
            vbar = Scrollbar(master)
            self.v_scrollbar(vbar, widget, x, y, w, h, pw, ph)
        if is_hbar:
            hbar = Scrollbar(master, orient="horizontal")
            self.h_scrollbar(hbar, widget, x, y, w, h, pw, ph)
        self.scrollbar_autohide(vbar, hbar, widget)

    def __tk_button_lyck9g7u(self, parent):
        btn = Button(parent, text="开启", takefocus=False, command=self.open)
        btn.place(x=20, y=10, width=50, height=30)
        return btn

    def __tk_button_lyck9i7l(self, parent):
        btn = Button(parent, text="关闭", takefocus=False, command=self.close_video)
        btn.place(x=90, y=10, width=50, height=30)
        return btn

    def __tk_canvas_lyck9nuu(self, parent):
        canvas = Canvas(parent, bg="#aaa")
        canvas.place(x=20, y=50, width=350, height=250)
        return canvas

    def open(self):
        self.video = cv2.VideoCapture(0)
        if not self.video.isOpened():
            messagebox.showinfo("提示", "无法开启摄像头！")
        elif self.video_open:
            messagebox.showinfo("提示", "摄像头属于开启状态！")
        else:
            #messagebox.showinfo("提示", "启动成功！")
            task = Thread(target=self.show)
            # 设置线程为守护线程，防止退出主线程时，子线程仍在运行
            task.setDaemon(True)
            task.start()

    def show(self):
        image = tkinter.Label(self.tk_canvas_canvas, text=' ', width=340, height=240)
        image.pack(fill=BOTH, expand=YES)
        self.video_open = True
        abc = None # 用来存储照片 防止tkinter显示图片闪烁
        while self.video_open:
            res, img = self.video.read()
            if res == True:
                # 将adarray转化为image from tkinter import * 导入时 可能会与冲突 Image
                img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR) # 更改图片格式
                img = Image.fromarray(img)
                # 显示图片到label
                img = ImageTk.PhotoImage(img)
                image.image = img
                image['image'] = img
                abc = img

        # 创建一个定时器，每10ms进入一次函数 这种的无法根据按钮关闭
        # self.after(1, self.show)

    def close_video(self):
        self.confirm()
        self.video_open = False
        # 关闭
        self.video.release()
        # 清空画布上的所有信息
        time.sleep(1)
        self.clear_widgets(self.tk_canvas_canvas)

    @staticmethod
    def confirm():
        result = messagebox.askyesno("Confirmation", "Do you want to proceed?")
        if result:
            print("User clicked yes.")
        else:
            print("User clicked no.")

    def clear_widgets(self, frame):
        # 清空子组件
        for widget in frame.winfo_children():
            widget.destroy()




def test():


    # 创建一个TK界面
    root = tkinter.Tk()
    root.geometry("640x480")
    root.resizable(False, False)
    root.title('video')



    def imshow():
        global video
        global root
        global image
        res, img = video.read()

        if res == True:
            # 将adarray转化为image
            img = Image.fromarray(img)
            # 显示图片到label
            img = ImageTk.PhotoImage(img)
            image.image = img
            image['image'] = img
        # 创建一个定时器，每10ms进入一次函数
        root.after(10, imshow)

        video.release()

    # 创建label标签
    image = tkinter.Label(root, text=' ', width=640, height=480)
    image.place(x=0, y=0, width=640, height=480)

    imshow()

    root.mainloop()

    # 释放video资源
    video.release()


if __name__ == "__main__":
    win = WinGUI()
    win.mainloop()



